package com.yupi.springbootinit.statemachine.service.impl;

import com.yupi.springbootinit.statemachine.core.StateContext;
import com.yupi.springbootinit.statemachine.core.StateProcessor;
import com.yupi.springbootinit.statemachine.core.TransitionResult;
import com.yupi.springbootinit.statemachine.enums.OrderStateEnum;
import com.yupi.springbootinit.statemachine.enums.ProcessInstanceStateEnum;
import com.yupi.springbootinit.statemachine.permission.PermissionManager;
import com.yupi.springbootinit.statemachine.rule.RuleEngine;
import com.yupi.springbootinit.statemachine.rule.RuleValidationResult;
import com.yupi.springbootinit.statemachine.service.AutoProgressService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * StateMachineServiceImpl辅助类
 * 包含验证和事件发布等辅助方法
 */
@Slf4j
@Component
public class StateMachineServiceImplHelper {
    
    /**
     * 验证状态上下文参数
     */
    public static boolean validateContext(StateContext context) {
        if (context == null) {
            log.error("状态上下文不能为空");
            return false;
        }
        
        if (context.getEntityId() == null) {
            log.error("实体ID不能为空");
            return false;
        }
        
        if (context.getEntityType() == null || context.getEntityType().trim().isEmpty()) {
            log.error("实体类型不能为空");
            return false;
        }
        
        if (context.getCurrentState() == null) {
            log.error("当前状态不能为空");
            return false;
        }
        
        if (context.getTargetState() == null) {
            log.error("目标状态不能为空");
            return false;
        }
        
        return true;
    }
    
    /**
     * 验证权限
     */
    public static boolean validatePermission(StateContext context, PermissionManager permissionManager) {
        try {
            // 获取当前用户信息
            Long operatorId = context.getOperatorId();
            if (operatorId == null) {
                log.warn("操作用户ID为空，跳过权限验证");
                return true; // 系统自动操作，跳过权限验证
            }
            
            // 检查用户是否有执行此状态转换的权限
            boolean hasPermission = permissionManager.validateStateTransition(context);
            
            if (!hasPermission) {
                log.warn("用户权限不足: 用户ID={}, 状态转换={} -> {}", 
                        operatorId, 
                        context.getCurrentState().getCode(),
                        context.getTargetState().getCode());
            }
            
            return hasPermission;
            
        } catch (Exception e) {
            log.error("权限验证异常", e);
            return false;
        }
    }
    
    /**
     * 验证业务规则
     */
    public static RuleValidationResult validateBusinessRules(StateContext context, RuleEngine ruleEngine) {
        try {
            return ruleEngine.validateTransition(context);
        } catch (Exception e) {
            log.error("业务规则验证异常", e);
            return RuleValidationResult.failure("业务规则验证异常: " + e.getMessage(), "RULE_VALIDATION_ERROR");
        }
    }
    
    /**
     * 获取状态处理器
     */
    public static StateProcessor getStateProcessor(String entityType, Map<String, StateProcessor> stateProcessors) {
        return stateProcessors.get(entityType);
    }
    
    /**
     * 发布状态变更事件
     */
    public static void publishStateChangeEvent(StateContext context, TransitionResult result, ApplicationEventPublisher eventPublisher) {
        try {
            String entityType = context.getEntityType();
            
            if ("ORDER".equals(entityType)) {
                // 发布订单状态变更事件
                AutoProgressService.OrderStateChangeEvent orderEvent = new AutoProgressService.OrderStateChangeEvent(
                        context.getEntityId(),
                        (OrderStateEnum) context.getCurrentState(),
                        (OrderStateEnum) context.getTargetState(),
                        context.getOperatorId() != null ? context.getOperatorId().toString() : "SYSTEM"
                );
                eventPublisher.publishEvent(orderEvent);
                
                log.debug("发布订单状态变更事件: 订单ID={}, {} -> {}", 
                        context.getEntityId(),
                        context.getCurrentState().getCode(),
                        context.getTargetState().getCode());
                
            } else if ("PROCESS_INSTANCE".equals(entityType)) {
                // 发布工序实例状态变更事件
                Long orderId = context.getParameter("orderId", Long.class);
                if (orderId == null) {
                    // 如果没有传入订单ID，尝试从业务数据中获取
                    orderId = extractOrderIdFromProcessInstance(context.getEntityId());
                }
                
                AutoProgressService.ProcessInstanceStateChangeEvent processEvent = new AutoProgressService.ProcessInstanceStateChangeEvent(
                        context.getEntityId(),
                        orderId,
                        (ProcessInstanceStateEnum) context.getCurrentState(),
                        (ProcessInstanceStateEnum) context.getTargetState(),
                        context.getOperatorId() != null ? context.getOperatorId().toString() : "SYSTEM"
                );
                eventPublisher.publishEvent(processEvent);
                
                log.debug("发布工序实例状态变更事件: 工序ID={}, 订单ID={}, {} -> {}", 
                        context.getEntityId(),
                        orderId,
                        context.getCurrentState().getCode(),
                        context.getTargetState().getCode());
            }
            
        } catch (Exception e) {
            log.error("发布状态变更事件失败", e);
            // 不抛出异常，避免影响主业务流程
        }
    }
    
    /**
     * 从工序实例ID提取订单ID
     * 实际应用中应该查询数据库获取
     */
    private static Long extractOrderIdFromProcessInstance(Long processInstanceId) {
        // 简化实现：假设工序实例ID的前几位是订单ID
        if (processInstanceId != null && processInstanceId > 100) {
            return processInstanceId / 100;
        }
        return null;
    }
}